package com.cygsunri.wisdompark.util;

import com.cygsunri.exception.BusinessException;
import com.cygsunri.response.ResultCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.io.*;
import java.lang.reflect.Field;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
public class CommonUtil {

    /**
     *取固定位数的随机数
     * @param num int 位数
     * @return String
     */
    public static String getRandom(int num){
        Random r = new Random();
        String result="";
        if (num > 0) {
            for (int i = 0; i < num; i++) {
                result+= r.nextInt(10);
            }
        } else {
            r.nextInt();
            return r.toString();
        }
        return result;
    }
    /**
     *取系统时间戳（毫秒级）
     * @return String
     */
    public static String getSystimeMillis(){
        long currentTime = System.currentTimeMillis();
        return String.valueOf(currentTime);
    }
    /**
     *取系统时间戳（秒级）
     * @return String
     */
    public static String getSystimeSecs(){
        long currentTime = System.currentTimeMillis()/1000;
        return String.valueOf(currentTime);
    }
    /**
     *利用MD5加密字符串
     * @return String
     */
    public static String getJieshunEncrypt(String orgStr){

        return MD5Util.encrypt(orgStr);
    }
    /**
     *获取UUID
     * @return String
     */
    public static String getUUID(){
        UUID uuid = UUID.randomUUID();
        return uuid.toString().replace("-","");
    }

    /**
     * 读取json文件
     * @param fileName
     * @return
     */
    public static String readJsonFile(String fileName) {
        String jsonStr = "";
        try {
            File jsonFile = new File(fileName);
            FileReader fileReader = new FileReader(jsonFile);
            Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
            int ch = 0;
            StringBuffer sb = new StringBuffer();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            fileReader.close();
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 将Object对象里面的属性和值转化成Map对象
     *
     * @param obj
     * @return
     * @throws IllegalAccessException
     */
    public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
        Map<String, Object> map = new HashMap<String,Object>();
        Class<?> clazz = obj.getClass();
        List<Field> fields = new ArrayList<>();
        //把父类包含的字段遍历出来
        while (clazz!=null){
            fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass();
        }
        for (Field field : fields) {
            field.setAccessible(true);
            String fieldName = field.getName();
            Object value = field.get(obj);
            //如果参数的值为空不参与签名(为空的标准是str==null,str.length()==0,值是否包含空白字符)
            if(value!=null&&StringUtils.isNotBlank(value.toString())){
                map.put(fieldName, value);
            }
        }
        return map;
    }

    /**
     *  根据map的key进行字典升序排序
     * @param map
     * @return map
     */
    public static Map<String, Object> sortMapByKey(Map<String, Object>map) {
        Map<String, Object> treemap = new TreeMap<String, Object>(map);
        List<Map.Entry<String, Object>> list = new ArrayList<Map.Entry<String, Object>>(treemap.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, Object>>() {
            @Override
            public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                return o1.getKey().compareTo(o2.getKey());
            }
        });
        return treemap;
    }

    /**
     * 将map转换成url参数
     * @param map
     * @return
     */
    public static String getUrlParamsByMap(Map<String, Object> map) {
        if (map == null) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        try {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                Object valueTemp = entry.getValue();
                if(valueTemp!=null){
                    //String value = URLEncoder.encode(valueTemp.toString(), "UTF-8");
                    String value = valueTemp.toString();
                    sb.append(entry.getKey() + "=" + value);
                    sb.append("&");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        String s = sb.toString();
        if (s.endsWith("&")) {
            s = StringUtils.substringBeforeLast(s, "&");
        }
        return s;
    }

    public static void saveImageToDisk(String imgUrl,String filePath) {
        InputStream inputStream = null;
        inputStream = getInputStream(imgUrl);//调用getInputStream()函数。
        if(inputStream ==null){
            throw new BusinessException(ResultCodeEnum.SYS_ERROR.getCode(),"图片地址无效,请核实!");
        }
        byte[] data = new byte[1024];
        int len = 0;

        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(filePath);//初始化一个FileOutputStream对象
            while ((len = inputStream.read(data))!=-1) {//循环读取inputStream流中的数据，存入文件流fileOutputStream
                fileOutputStream.write(data,0,len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{//finally函数，不管有没有异常发生，都要调用这个函数下的代码
            if(fileOutputStream!=null){
                try {
                    fileOutputStream.close();//记得及时关闭文件流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(inputStream!=null){
                try {
                    inputStream.close();//关闭输入流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public static InputStream getInputStream(String imgUrl){
        InputStream inputStream = null;
        HttpURLConnection httpURLConnection = null;
        try {
            String strUrl = new String(imgUrl.getBytes("iso-8859-1"), "utf-8");
            String encodeUrl = URLEncoder.encode(imgUrl, "utf-8");
            String decode = URLDecoder.decode(imgUrl, "utf-8");
            log.info("imgUrl ==>> "+imgUrl +"strUrl ==>> "+strUrl + " encodeUrl ==>> "+encodeUrl + " decode ==>> "+decode);
            URL url = new URL(imgUrl);//创建的URL
            if (url!=null) {
                httpURLConnection = (HttpURLConnection) url.openConnection();//打开链接
                httpURLConnection.setConnectTimeout(50000);//设置网络链接超时时间，3秒，链接失败后重新链接
                httpURLConnection.setReadTimeout(50000);
                httpURLConnection.setDoInput(true);//打开输入流
                httpURLConnection.setRequestMethod("GET");//表示本次Http请求是GET方式
                httpURLConnection.addRequestProperty("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36");
                httpURLConnection.connect();
                int responseCode = httpURLConnection.getResponseCode();//获取返回码
                log.info("response:"+httpURLConnection.getResponseCode()+"    "+httpURLConnection.getResponseMessage());
                log.info(httpURLConnection.toString());
                if (responseCode == 200) {//成功为200
                    //从服务器获得一个输入流
                    inputStream = httpURLConnection.getInputStream();
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return inputStream;

    }

    /**
     * 计算两个时间差(时分秒)
     * @param startTime
     * @param endTime
     * @return
     */
    public static String getDateDistance (String startTime,String endTime) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateDistance = "";
        try {
            Date startDate = format.parse(startTime);
            Date endDate = format.parse(endTime);
            long diff = endDate.getTime() - startDate.getTime();
            long diffSeconds = diff / 1000 % 60;//秒
            long diffMinutes = diff / (60 * 1000) % 60;//分钟
            long diffHours = diff / (60 * 60 * 1000) % 24;//小时
            //long diffDays = diff / (24 * 60 * 60 * 1000);//天
            dateDistance = diffHours+":"+diffMinutes+":"+diffSeconds;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dateDistance;
    }

    /**
     * 对当前路径判断时文件或是文件夹进行权限的修改
     *
     * @param filePath 文件路径
     */
    public static void changeFolderPermission(String filePath) {
        File file = new File(filePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                ensureFolderPermission(files[i]);
            }
        } else {
            ensureFolderPermission(file);
        }
    }

    /**
     * 实现文件权限修改的方法
     * Linux环境中权限的区别
     * drwxrwxrwx:777的权限，对应的组别依次是文件的属主，用户组，其他；权限依次是可读(4)，可写(2)，可执行(1)
     *
     * @param dirFile 文件或文件夹
     */
    private static void ensureFolderPermission(File dirFile) {
        try {
            Set<PosixFilePermission> permissionSet = new HashSet<PosixFilePermission>();
            Path path = Paths.get(dirFile.getAbsolutePath());
            // 设置的权限为-rwxrwxrwx
            permissionSet.add(PosixFilePermission.OWNER_READ);
            permissionSet.add(PosixFilePermission.OWNER_WRITE);
            permissionSet.add(PosixFilePermission.OWNER_EXECUTE);
            permissionSet.add(PosixFilePermission.GROUP_READ);
            permissionSet.add(PosixFilePermission.GROUP_WRITE);
            permissionSet.add(PosixFilePermission.GROUP_EXECUTE);
            permissionSet.add(PosixFilePermission.OTHERS_READ);
            permissionSet.add(PosixFilePermission.OTHERS_WRITE);
            permissionSet.add(PosixFilePermission.OTHERS_EXECUTE);
            Files.setPosixFilePermissions(path, permissionSet);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
